package com.ff.xyh.access.controller.access;


import com.ff.xyh.common.entity.result.ResultMessage;
import com.ff.xyh.common.entity.result.ResultObject;
import com.ff.xyh.common.entity.useraccess.AccessUser;
import com.ff.xyh.common.utils.MD5;
import com.ff.xyh.common.qo.access.AccessUserQuery;
import com.ff.xyh.access.service.access.AccessUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 * 后台用户表 前端控制器
 * </p>
 *
 * @author ff
 * @since 2022-10-25
 */
@Api(tags = "后台用户相关接口")
@RestController
@CrossOrigin
@RequestMapping("/access/user")
public class AccessUserController {
    @Autowired
    private AccessUserService accessUserService;

    //登录 前端需要把token写入cookie 发送请求时作为请求头
//    @ApiOperation(value = "登录测试")
//    @PostMapping("loginTest")
//    public ResultObject loginTest(
//            @RequestParam(name = "userToken") String userToken,
//            @RequestParam(name = "password") String password) {
//        System.out.println("userToken ===> " + userToken);
//        System.out.println("password ===> " + password);
//        String token = accessUserService.login(userToken, password);
//        System.out.println(token);
//        return ResultObject.ok().data("token", token);
//    }


//    /**
//     * 后台用户注册
//     * @param accessUser
//     * @return
//     */
//    @ApiOperation(value = "注册")
//    @PostMapping("register")
//    public ResultObject register (
//            @RequestBody AccessUser accessUser) {
//        if (accessUserService.register(accessUser)) {
////            String token = JwtUtils.createJwtTokenWithUserId(accessUser.getId());
////            map.put("token", token); // 可以用于直接登录
//            accessUser.setPassword("");
//            return ResultObject.ok().data("user", accessUser);
//        } else
//            return ResultObject.error().message("注册失败");
//    }

    @ApiOperation(value = "添加后台用户")
    @PostMapping("add")
    public ResultObject addAccessUser (
            @RequestBody AccessUser accessUser) {
        if (accessUserService.register(accessUser)) {
//            String token = JwtUtils.createJwtTokenWithUserId(accessUser.getId());
//            map.put("token", token); // 可以用于直接登录
            return ResultObject.ok().data("data", accessUser);
        } else
            return ResultObject.error().message("注册失败");
    }

    @ApiOperation(value = "删除后台用户")
    @GetMapping("delete/{userId}")
    @PreAuthorize("hasAnyAuthority('accessUser.delete')")
    public ResultObject deleteAccessUser (
            @PathVariable String userId) {
        if (userId.equals("1000000000000000000")) {
            return ResultObject.error().message("超级管理员不可被删除");
        }
        AccessUser accessUser = accessUserService.getById(userId);
        if (accessUser == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }
        if (accessUserService.deleteAccessUserById(userId)) {
//            String token = JwtUtils.createJwtTokenWithUserId(accessUser.getId());
//            map.put("token", token); // 可以用于直接登录
            return ResultObject.ok().data("data", accessUser);
        } else {
            return ResultObject.error().message("删除失败");
        }
    }

    @ApiOperation(value = "修改后台用户信息 不会修改密码")
    @PostMapping("modify/user")
    public ResultObject modifyAccessUser (
            @RequestBody AccessUser accessUser) {
        AccessUser existOne = accessUserService.getById(accessUser.getId());
        if (existOne == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        } else {
            accessUser.setPassword(existOne.getPassword());
            if (accessUserService.updateById(accessUser)) {
                return ResultObject.ok();
            } else {
                return ResultObject.error().message(ResultMessage.OBJECT_EXISTS_BUT_FAILED_TO_UPDATE);
            }
        }
    }


//    /**
//     * 通过token查询用户基本信息
//     * @param token
//     * @return
//     */
//    @ApiOperation(value = "获取当前用户基本信息 在请求头中传入token")
//    @GetMapping("get/currentUserBase/token")
//    public ResultObject getCurrentUserBaseInfoByToken (
//            @RequestParam(name = "token") String token) {
//        try {
//            AccessUser accessUser = accessUserService.getById(JwtUtils.getSubjectFromToken(token));
//            if (accessUser == null) {
//                return ResultObject.ok().message(ResultMessage.NO_SUCH_OBJECT);
//            } else {
//                UserBaseInfo userBaseInfo = new UserBaseInfo();
//                BeanUtils.copyProperties(accessUser, userBaseInfo);
//                userBaseInfo.setToken(token);
//                return ResultObject.ok().setDataAndCheckNull("data", userBaseInfo);
//            }
//        } catch (NullPointerException e) {
//            throw new MyException(20001, "token取不到值");
//        }
//    }

//    @ApiOperation(value = "获取当前用户基本信息 在请求头中传入token")
//    @GetMapping("get/currentUserBase")
//    public ResultObject getCurrentUserBaseInfo (
//            HttpServletRequest request) {
//        String jwtToken = request.getHeader("token");
//        UserBaseInfo userBaseInfo;
//        if (StringUtils.isEmpty(jwtToken)) {
//            return ResultObject.error().message(ResultMessage.ERROR_ARG);
//        }
//        try {
//            AccessUser accessUser = accessUserService.getById(JwtUtils.getSubjectFromToken(jwtToken));
//            if (accessUser == null) {
//                return ResultObject.ok().message(ResultMessage.NO_SUCH_OBJECT);
//            } else {
//                userBaseInfo = new UserBaseInfo();
//                BeanUtils.copyProperties(accessUser, userBaseInfo);
//                return ResultObject.ok().setDataAndCheckNull("data", userBaseInfo);
//            }
//        } catch (NullPointerException e) {
//            throw new MyException(20001, "token取不到值");
//        }
//    }

//    已经集成在条件查询里了
//    /**
//     * 通过id查询用户所有信息
//     * @param id
//     * @return
//     */
//    @ApiOperation(value = "根据id获取用户信息")
//    @GetMapping("get/{id}")
//    public ResultObject getUserById (
//            @PathVariable String id ) {
//        AccessUser frontUser = accessUserService.getById(id);
//        return ResultObject.ok().data("user", frontUser);
//    }

    @ApiOperation(value = "用户自身修改密码")
    @PostMapping("modify/user/password")
    @PreAuthorize("hasAnyAuthority('accessUser.modify')")
    public ResultObject updatePassword (
            @RequestParam(name = "oldPassword") String oldPassword,
            @RequestParam(name = "newPassword") String newPassword) {
        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        AccessUser exist = accessUserService.getById(userId);
        if (exist == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        } else {
            if (exist.getPassword().equals(MD5.encrypt(oldPassword))) {
                if (accessUserService.updatePassword(exist.getId(), newPassword)) {
                    return ResultObject.ok().message("密码修改成功，请重新登录");
                } else {
                    return ResultObject.ok().message("未知错误，修改失败");
                }
            } else {
                return ResultObject.error().message("原密码不正确");
            }
        }
    }
    @ApiOperation(value = "管理员修改密码")
    @PostMapping("modify/password")
    public ResultObject updateUserPassword (
            @RequestParam(name = "userId") String userId,
            @RequestParam(name = "password") String password) {
        if (accessUserService.updatePassword(userId, password))
            return ResultObject.ok().message("密码修改成功，请重新登录");
        else
            return ResultObject.error().message(ResultMessage.FAILED_TO_UPDATE);
    }

    /**
     * 获取具有特定权限的所有管理员
     * @param permissionId
     * @return
     */
    @ApiOperation(value = "根据permissionId获取所有用户")
    @GetMapping("get/permission/{permissionId}")
    public ResultObject getUsersByPermissionId (
            @PathVariable String permissionId ) {
        List<AccessUser> accessUserList = accessUserService.getAllAccessUserWithPermissionId(permissionId);
        if (accessUserList == null || accessUserList.isEmpty())
            return ResultObject.error().message(ResultMessage.NO_RESULT);
        else
            return ResultObject.ok().putList(accessUserList, accessUserList.size());
    }

    /**
     * 获取特定角色的所有管理员
     * @param roleId
     * @return
     */
    @ApiOperation(value = "根据roleId获取所有用户")
    @GetMapping("get/role/{roleId}")
    public ResultObject getUsersByRoleId (
            @RequestParam(name = "roleId") String roleId ) {
        List<AccessUser> accessUserList = accessUserService.getAllAccessUserWithRoleId(roleId);
        if (accessUserList == null || accessUserList.isEmpty())
            return ResultObject.error().message(ResultMessage.NO_RESULT);
        else
            return ResultObject.ok().data("items", accessUserList);
    }

    @ApiOperation(value = "条件查询用户列表")
    @PostMapping("get/list/query")
    //传一个参数
    // @PreAuthorize("hasAuthority('system:dept:list')")
    //传多个参数
    // @PreAuthorize("hasAnyAuthority('system:dept:list,system:test:list')")
    // 传一个参数，需要拼接前缀
    // @PreAuthorize("hasRole('system:dept:list,system:test:list')")
    @PreAuthorize("hasAnyAuthority('accessUser.list')")
    public ResultObject getUserListQuery (
            @RequestBody AccessUserQuery accessUserQuery) {
//        if (accessUserQuery.getSex() == null)
//            System.out.println("sex is null");
//        else if (accessUserQuery.getSex() == 0)
//            System.out.println("sex is 0");
        List<AccessUser> resultList = accessUserService.getUserListQuery(accessUserQuery);
        if (resultList == null || resultList.isEmpty()) {
            return ResultObject.error().message(ResultMessage.NO_RESULT);
        } else {
            resultList.stream().forEach(accessUser -> accessUser.setPassword(""));
            return ResultObject.ok().data("items", resultList);
        }
    }


}

